<?php

namespace App\Exceptions;

use App\Services\Utils\FormatLog;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        ApiSilentException::class
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception $exception
     * @return void
     * @throws Exception
     */
    public function report(Exception $exception)
    {
//        $this->sentryReport($exception);
        
        $this->logUncaughtRequest($exception);

        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     */
    public function render($request, Exception $exception)
    {
        return parent::render($request, $exception);
    }

    /**
     * @param Exception $exception
     */
    private function sentryReport(Exception $exception): void
    {
        /**
         * sentry 收集错误还没找到定期清理的设置，先不要log
         *
         * @link https://laravel-china.org/articles/4285/build-your-own-sentry-service - 本地sentry服务器搭建
         */
        if ($this->shouldReport($exception)) {
            app('sentry')->captureException($exception);
        }
    }

    private function logUncaughtRequest(Exception $e): void
    {
        if ($this->shouldntReport($e) ||
            $e instanceof ApiAbstractException) {
            return;
        }

        $method_path = FormatLog::request();
        logger()->error($method_path);

        /** @var array|string $req - hack for log error type hint need string */
        $req = request()->all();
        if ($req) {
            logger()->error(PHP_EOL. request());
            logger()->error($req);
        }
    }
}
